package com.activities;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.model.CategorySeries;
import org.achartengine.renderer.DefaultRenderer;
import org.achartengine.renderer.SimpleSeriesRenderer;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.MimeTypeMap;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.Utility.Configs;
import com.Utility.DownloadManager;
import com.Utility.MessageManager;
import com.Utility.Utility;
import com.Utility.WebServiceCommunicator.WebServiceFlag;
import com.activities.group.TabBaseGroupActivity;
import com.adapters.ContactsAdapter;
import com.adapters.VaultFilesCheckAdapter;
import com.controls.ws.VaultWSControl;
import com.dialogs.DeleteConfirmDialog;
import com.events.WebServiceCommunicatorListener;
import com.objects.VaultFile;
import com.parser.Error_Report;
import com.senditcertified.mail.R;
import com.soap.call.Http_Soap_Call;
import com.views.NoScrollListView;

public class VaultActivity extends BaseActivity implements OnClickListener,
		OnItemClickListener, WebServiceCommunicatorListener {

	private static final int RQ_CHOOSE_FILE = 6384;
	private GraphicalView mChartView2;
	private DefaultRenderer renderer;
	private CategorySeries categorySeries;
	private static int[] COLORS = new int[] { Color.parseColor("#009600"),
			Color.parseColor("#f79218") };
	private LinearLayout chart_layout;
	private NoScrollListView mLstViewVault;
	private TextView vault_capacity_tv, vault_used_space_tv,
			vault_free_space_tv, tvFileName, tvFileSize, tvFileDate;
	private ImageView vault_open, vault_refresh_iv, vault_delete_iv,
			vault_upload, vault_download;
	private CheckBox mCbSellectAll;
	private String capacityCaption, usedCaption, freeCaption, usedPercent,
			freePercent;
	private VaultFilesCheckAdapter mAdapter;
	private String uploadFilePath;
	private boolean isDateSort = false;
	private boolean isFileNameSort = false;
	private boolean isFileSizeSort = false;
	// dialog
	private ProgressDialog mDialog;
	// webservice
	private VaultWSControl mWSVault;
	private DownloadManager downloadTool;
	// task
	private UploadFileTask mUploadFileTask;
	private DeleteConfirmDialog mDeleteConfirmDialog;

	public void vaultActivityResult(int requestCode, int resultCode, Intent data) {
		Log.e("vault", "onActivityResult: " + requestCode + ", " + resultCode);
		if (requestCode == RQ_CHOOSE_FILE && resultCode == RESULT_OK) {
			if (data != null && data.getData() != null) {
				String path = data.getData().getPath();
				if (!DownloadManager.isExist(path)) {
					path = getPath(data.getData());
				}
				if (!TextUtils.isEmpty(path)) {
					Log.e("Vault", path);
					File f = new File(path);
					uploadFilePath = f.getAbsolutePath();
					if (mUploadFileTask != null) {
						mUploadFileTask.cancel(true);
						mUploadFileTask = null;
					}
					mUploadFileTask = new UploadFileTask();
					mUploadFileTask.execute(uploadFilePath);
				} else {
					MessageManager.showToast(this, "Can't get this file");
				}
			} else {
				MessageManager.showToast(this, "Can't get this file");
			}
		}

	}

	private void openFileDialog() {
		try {
			if (mAdapter != null) {
				ArrayList<VaultFile> lstChoosed = mAdapter
						.getVaultChoosedList();
				if (lstChoosed.size() == 0) {
					MessageManager.showToast(this,
							"Please select file(s) to open.");
				} else if (lstChoosed.size() == 1) {
					openFile(lstChoosed.get(0).getName());
				} else if (lstChoosed.size() > 3) {
					Utility.showAlert(getParent(),
							"You can select maximum 3 files at a time.");
				} else {
					TabBaseGroupActivity parentActivity = (TabBaseGroupActivity) getParent();
					Intent intent = new Intent(getParent(),
							VaultFileListActivity.class);
					intent.putExtra("open", lstChoosed);
					parentActivity.startChildActivity("open", intent);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private class UploadFileTask extends AsyncTask<String, Void, String> {
		private File uploadFile;
		private Error_Report repor = new Error_Report();

		@Override
		protected void onPreExecute() {
			if (mDialog != null) {
				mDialog.dismiss();
				mDialog = null;
			}

			mDialog = new ProgressDialog(getParent());
			mDialog.setMessage(getString(R.string.uploading));
			mDialog.setCancelable(false);
			mDialog.show();
		}

		@Override
		protected String doInBackground(String... params) {
			uploadFile = new File(params[0]);
			try {
				if (uploadFile.exists()) {

					byte b[][] = toByteArray(uploadFile, 262144);

					Http_Soap_Call call = Http_Soap_Call.create_connection("",
							getParent());
					if (call != null && b != null) {
						for (int i = 0; i < b.length; i++) {
							call.GetUploadFileResponse(Utility
									.getStringPreference(getParent(),
											"LoginToken", "1"), params[0],
									b[i], i * 262144, repor);
						}

					} else {
						return "No Connection!";
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
				return e.getMessage();
			} catch (OutOfMemoryError e) {
				e.printStackTrace();
				return e.getMessage();
			}

			return "OK";
		}

		@Override
		protected void onPostExecute(String result) {
			if (mDialog != null) {
				mDialog.dismiss();
				mDialog = null;
			}
			if ("OK".equals(result)) {
				mWSVault.getVaultStatistics(Utility.getStringPreference(
						getParent(), Utility.KEY_LOGIN_TOKEN, "1"));
			} else {
				MessageManager.showToast(VaultActivity.this, result);
			}
		}

	}

	public byte[][] toByteArray(File file, int byteBlockSize)
			throws IOException {
		if (file.exists()) {
			InputStream in = new FileInputStream(file);
			long noOfBlocks = (long) Math.ceil((double) file.length()
					/ (double) byteBlockSize);
			byte[][] result = new byte[(int) noOfBlocks][byteBlockSize];
			int offset = 0;
			for (int i = 0; i < result.length; i++) {
				result[i] = readByteBlock(in, offset, byteBlockSize);
			}
			return result;
		} else
			return null;
	}

	private byte[] readByteBlock(InputStream in, int offset, int noBytes)
			throws IOException {
		byte[] result = new byte[noBytes];
		in.read(result, offset, noBytes);
		return result;
	}

	private class aChart_Example {
		// private GraphicalView mChartView2;
		int count = COLORS.length;

		public Intent execute(Context context, LinearLayout parent) {
			int[] colors = new int[count];
			for (int i = 0; i < count; i++) {
				colors[i] = COLORS[i];
			}

			renderer = buildCategoryRenderer(colors);
			renderer.setZoomEnabled(false);
			renderer.setPanEnabled(false);// Disable User Interaction
			renderer.setLabelsColor(Color.BLACK);
			renderer.setShowLabels(true);
			renderer.setShowLegend(false);
			renderer.setLabelsTextSize(12);
			renderer.setInScroll(true);
			categorySeries = new CategorySeries("");
			categorySeries.add(freePercent, Double.parseDouble(freePercent));
			categorySeries.add(usedPercent, Double.parseDouble(usedPercent));

			mChartView2 = ChartFactory.getPieChartView(context, categorySeries,
					renderer);
			parent.addView(mChartView2);

			return ChartFactory.getPieChartIntent(context, categorySeries,
					renderer, null);
		}

		protected DefaultRenderer buildCategoryRenderer(int[] colors) {
			DefaultRenderer renderer = new DefaultRenderer();
			for (int color : colors) {
				SimpleSeriesRenderer r = new SimpleSeriesRenderer();
				r.setColor(color);
				renderer.addSeriesRenderer(r);
			}
			return renderer;
		}
	}

	@Override
	protected int initLayout() {
		return R.layout.activity_vault;
	}

	@Override
	protected void initViews() {
		mCbSellectAll = (CheckBox) findViewById(R.id.vault_select_cb);
		mLstViewVault = (NoScrollListView) findViewById(R.id.list);
		chart_layout = (LinearLayout) findViewById(R.id.chart_ll);
		vault_capacity_tv = (TextView) findViewById(R.id.vault_capacity_tv);
		vault_used_space_tv = (TextView) findViewById(R.id.vault_used_space_tv);
		vault_free_space_tv = (TextView) findViewById(R.id.vault_free_space_tv);
		vault_refresh_iv = (ImageView) findViewById(R.id.vault_refresh);
		vault_delete_iv = (ImageView) findViewById(R.id.vault_delete);
		vault_open = (ImageView) findViewById(R.id.vault_open);
		vault_download = (ImageView) findViewById(R.id.vault_download);
		vault_upload = (ImageView) findViewById(R.id.vault_upload);
		tvFileName = (TextView) findViewById(R.id.heading_file_name_tv);
		tvFileSize = (TextView) findViewById(R.id.heading_file_size_tv);
		tvFileDate = (TextView) findViewById(R.id.heading_file_date_tv);

	}

	@Override
	protected void initComponents() {
		mWSVault = new VaultWSControl(this, this);
		mWSVault.getVaultStatistics(Utility.getStringPreference(getParent(),
				Utility.KEY_LOGIN_TOKEN, "1"));
		mLstViewVault.setDivider(0);

		downloadTool = new DownloadManager(this) {
			@Override
			public void onFinish() {
				if (mDialog != null) {
					mDialog.dismiss();
					mDialog = null;
				}
				AlertDialog.Builder builder = new AlertDialog.Builder(
						getParent());
				builder.setMessage(
						"File downloaded to sdcard/sendit.\nDo you want to open file?")
						.setCancelable(false)
						.setPositiveButton("Yes",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int id) {
										try {
											openFileDialog();
										} catch (Exception e) {
											e.printStackTrace();
										}
									}
								})
						.setNegativeButton("No",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int id) {
										// put your code here
										dialog.cancel();
									}
								});
				AlertDialog alertDialog = builder.create();
				alertDialog.show();

			}
		};
		downloadTool.prepareFolder(Configs.FILE_STORE);

	}

	@Override
	protected void addListener() {
		tvFileName.setOnClickListener(this);
		tvFileDate.setOnClickListener(this);
		tvFileSize.setOnClickListener(this);
		vault_refresh_iv.setOnClickListener(this);
		vault_delete_iv.setOnClickListener(this);
		mCbSellectAll.setOnClickListener(this);
		vault_open.setOnClickListener(this);
		vault_download.setOnClickListener(this);
		vault_upload.setOnClickListener(this);
		mLstViewVault.setOnItemClickListener(this);

	}

	@Override
	public void onClick(View v) {
		if (v == tvFileName) {
			if (mAdapter != null && mAdapter.getLst() != null
					&& mAdapter.getLst().size() > 0) {
				if (!isFileNameSort) {
					isFileNameSort = true;
					Collections.sort(mAdapter.getLst(),
							new Comparator<VaultFile>() {

								@Override
								public int compare(VaultFile firstObjToCompare,
										VaultFile secondObjToCompare) {
									return (firstObjToCompare.getName().toLowerCase(Locale.getDefault()))
											.compareTo(secondObjToCompare
													.getName().toLowerCase(Locale.getDefault()));
								}

							});
				} else {
					isFileNameSort = false;
					Collections.sort(mAdapter.getLst(),
							new Comparator<VaultFile>() {

								@Override
								public int compare(VaultFile firstObjToCompare,
										VaultFile secondObjToCompare) {
									return (secondObjToCompare.getName().toLowerCase(Locale.getDefault()))
											.compareTo(firstObjToCompare
													.getName().toLowerCase(Locale.getDefault()));
								}

							});
				}
				mAdapter.notifyDataSetChanged();
			}
		} else if (v == tvFileDate) {
			if (mAdapter != null && mAdapter.getLst() != null
					&& mAdapter.getLst().size() > 0) {
				if (!isDateSort) {
					isDateSort = true;
					Collections.sort(mAdapter.getLst(),
							new Comparator<VaultFile>() {

								@Override
								public int compare(VaultFile firstObjToCompare,
										VaultFile secondObjToCompare) {
									DateFormat f = new SimpleDateFormat(
											"mm/dd/yyyy hh:mm:ss aa");
									try {
										return f.parse(
												firstObjToCompare.getDate())
												.compareTo(
														f.parse(secondObjToCompare
																.getDate()));
									} catch (ParseException e) {
										throw new IllegalArgumentException(e);
									}
								}

							});
				} else {
					isDateSort = false;
					Collections.sort(mAdapter.getLst(),
							new Comparator<VaultFile>() {

								@Override
								public int compare(VaultFile firstObjToCompare,
										VaultFile secondObjToCompare) {
									DateFormat f = new SimpleDateFormat(
											"mm/dd/yyyy hh:mm:ss aa");
									try {
										return f.parse(
												secondObjToCompare.getDate())
												.compareTo(
														f.parse(firstObjToCompare
																.getDate()));
									} catch (ParseException e) {
										throw new IllegalArgumentException(e);
									}
								}

							});

				}
				mAdapter.notifyDataSetChanged();
			}

		} else if (v == tvFileSize) {
			if (mAdapter != null && mAdapter.getLst() != null
					&& mAdapter.getLst().size() > 0) {
				if (!isFileSizeSort) {
					isFileSizeSort = true;
					Collections.sort(mAdapter.getLst(),
							new Comparator<VaultFile>() {

								@Override
								public int compare(VaultFile lhs, VaultFile rhs) {
									String first = lhs.getSize().substring(0,
											lhs.getSize().indexOf(" "));
									String Second = rhs.getSize().substring(0,
											rhs.getSize().indexOf(" "));
									int firstSize = Integer.parseInt(first);
									int secondSize = Integer.parseInt(Second);
									Log.e("Size", firstSize + ", " + secondSize);
									int ret = 0;
									ret = firstSize - secondSize;
									return ret;
								}
							});
				} else {
					isFileSizeSort = false;
					Collections.sort(mAdapter.getLst(),
							new Comparator<VaultFile>() {

								@Override
								public int compare(VaultFile lhs, VaultFile rhs) {
									String first = lhs.getSize().substring(0,
											lhs.getSize().indexOf(" "));
									String Second = rhs.getSize().substring(0,
											rhs.getSize().indexOf(" "));
									int firstSize = Integer.parseInt(first);
									int secondSize = Integer.parseInt(Second);
									Log.e("Size", firstSize + ", " + secondSize);
									int ret = 0;

									ret = secondSize - firstSize;
									return ret;

								}

							});
				}
				mAdapter.notifyDataSetChanged();
			}
		} else if (v == vault_refresh_iv) {
			mWSVault.getVaultStatistics(Utility.getStringPreference(
					getParent(), Utility.KEY_LOGIN_TOKEN, "1"));
		} else if (v == vault_delete_iv) {
			if (mAdapter != null && mAdapter.getCount() > 0) {
				final String deleteOr = mAdapter.getVaultChoosed();
				if (deleteOr != null && deleteOr.length() > 0) {
					if (mDeleteConfirmDialog != null) {
						mDeleteConfirmDialog.dismiss();
						mDeleteConfirmDialog = null;
					}
					mDeleteConfirmDialog = new DeleteConfirmDialog(getParent()) {
						@Override
						public void onConfirm() {
							mWSVault.deleteFile(Utility.getStringPreference(
									VaultActivity.this,
									Utility.KEY_LOGIN_TOKEN, ""), deleteOr);
						}
					};
					mDeleteConfirmDialog.setTitle("Delete Selected File");
					mDeleteConfirmDialog
							.setMessage("Do you want to delete file(s)?");
					mDeleteConfirmDialog.show();
				} else {
					MessageManager.showToast(this,
							"Please select file(s) to delete.");
				}

			}
		} else if (v == vault_open) {
			try {
				openFileDialog();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (v == vault_download) {
			if (mAdapter != null) {
				ArrayList<VaultFile> lstChoosed = mAdapter
						.getVaultChoosedList();
				if (lstChoosed.size() == 0) {
					MessageManager.showToast(this,
							"Please select file to download.");
				} else {
					if (mDialog != null) {
						mDialog.dismiss();
						mDialog = null;
					}
					mDialog = new ProgressDialog(getParent());
					mDialog.setMessage(null);
					mDialog.setCancelable(false);
					mDialog.show();
					for (VaultFile vaultFile : lstChoosed) {
						downloadTool.download(vaultFile.getName());
					}
				}
			}
		} else if (v == vault_upload) {
			// showChooser();
			Intent chooseFile;
			chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
			chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
			chooseFile.setType("*/*");
			chooseFile = Intent.createChooser(chooseFile, "Choose a file");
			getParent().startActivityForResult(chooseFile, RQ_CHOOSE_FILE);
		} else if (v == mCbSellectAll) {
			if (mCbSellectAll.isChecked()) {
				mAdapter.setCheckMode(ContactsAdapter.MODE_CHECK_ALL);
				mAdapter.notifyDataSetChanged();
			} else {
				mAdapter.setCheckMode(ContactsAdapter.MODE_UNCHECK_ALL);
				mAdapter.notifyDataSetChanged();
			}
		}

	}

	@Override
	protected void onDestroy() {
		if (mUploadFileTask != null) {
			mUploadFileTask.cancel(true);
			mUploadFileTask = null;
		}
		if (mDialog != null) {
			mDialog.dismiss();
			mDialog = null;
		}
		if (mDeleteConfirmDialog != null) {
			mDeleteConfirmDialog.dismiss();
			mDeleteConfirmDialog = null;
		}
		if (mWSVault != null) {
			mWSVault.cancel();
			mWSVault = null;
		}
		super.onDestroy();
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position,
			long arg3) {
		if (mAdapter != null && mAdapter.getLst() != null
				&& mAdapter.getLst().size() > position) {
			openFile(mAdapter.getLst().get(position).getName());
		}

	}

	private void openFile(String fileName) {
		if (fileName != null && fileName.length() > 0) {
			File file = new File(Configs.FILE_STORE + fileName);
			if (file.exists()) {
				String type = "";

				Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
				Uri uri = Uri.fromFile(file);
				Log.e("FILE Uri:", uri.toString());
				String extension = MimeTypeMap.getFileExtensionFromUrl(file
						.getAbsolutePath());
				if (extension != null) {
					MimeTypeMap mime = MimeTypeMap.getSingleton();
					type = mime.getMimeTypeFromExtension(extension);
					Log.e("FILE MIME:", type + "");
				}
				if (TextUtils.isEmpty(type))
					intent.setDataAndType(Uri.fromFile(file), "*/*");
				else
					intent.setDataAndType(Uri.fromFile(file), type);

				try {
					startActivity(intent);
				} catch (ActivityNotFoundException e) {
					e.printStackTrace();
					Utility.showAlert(getParent(),
							"Application not found to open file.");
				}

			} else {
				mWSVault.getWebInterfaceVaultUrl(Utility.getStringPreference(
						getParent(), Utility.KEY_LOGIN_TOKEN, "1"), fileName);
			}
		}
	}

	@Override
	public void onConnectionOpen(WebServiceFlag flag) {
		if (mDialog != null) {
			mDialog.dismiss();
			mDialog = null;
		}
		mDialog = ProgressDialog.show(getParent(), null,
				getString(R.string.loader));

	}

	@Override
	public void onConnectionError(WebServiceFlag flag, String error) {
		if (mDialog != null) {
			mDialog.dismiss();
			mDialog = null;
		}
		MessageManager.showToast(this, error);

	}

	@Override
	public void onConnectionDone(WebServiceFlag flag, String response) {
		if (mDialog != null) {
			mDialog.dismiss();
			mDialog = null;
		}

		if (flag == WebServiceFlag.GET_WEB_INTERFACE_VAULT_URL) {
			// TODO
			String link = mWSVault.parseAction(response,
					"GetWebInterfaceVaultURLResult");
			if (link != null && link.startsWith("http")) {
				Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
				startActivity(i);
			}
		} else if (flag == WebServiceFlag.GET_VAULT_CATALOG) {
			mAdapter = new VaultFilesCheckAdapter(VaultActivity.this,
					mCbSellectAll, mWSVault.parseVaultFile(response)) {
				@Override
				public void notifyDataSetChanged() {
					mLstViewVault.notifyDataSetChanged();
				}
			};
			mLstViewVault.setAdapter(mAdapter);

		} else if (flag == WebServiceFlag.GET_VAULT_STATISTIC) {
			JSONObject js = mWSVault.parseVaultStatistics(response);
			if (js != null) {
				try {
					capacityCaption = js.getString("CapacityCaption");
					usedCaption = js.getString("UsedCaption");
					freeCaption = js.getString("FreeCaption");
					usedPercent = js.getString("UsedPercent");
					freePercent = js.getString("FreePercent");
				} catch (JSONException jsonException) {
				}

				if (!TextUtils.isEmpty(capacityCaption)) {
					vault_capacity_tv.setText(capacityCaption);
				}

				if (!TextUtils.isEmpty(freeCaption)) {
					vault_free_space_tv.setText(freeCaption);
				}

				if (!TextUtils.isEmpty(usedCaption)) {
					vault_used_space_tv.setText(usedCaption);
				}

				new aChart_Example().execute(VaultActivity.this, chart_layout);
				// if(Double.parseDouble(usedPercent) > 0.00){
				mWSVault.getVaultCatalog(Utility.getStringPreference(
						getParent(), Utility.KEY_LOGIN_TOKEN, "1"));
				// }
			}
		} else if (flag == WebServiceFlag.DELETE_VAULT_FILE) {
			String link = mWSVault.parseAction(response,
					"DeleteFilesFromVaultResult");
			if (link != null
					&& link.startsWith("The process cannot access the file")) {
				MessageManager.showToast(this,
						"Some files could not be deleted");
				mWSVault.getVaultStatistics(Utility.getStringPreference(
						getParent(), Utility.KEY_LOGIN_TOKEN, "1"));
			} else {
				if (mAdapter != null) {
					mAdapter.removeSelected();
				}
			}
		}

	}

	public String getPath(Uri uri) {
		String[] projection = { MediaStore.Images.Media.DATA };
		Cursor cursor = managedQuery(uri, projection, null, null, null);
		if (cursor != null) {
			// HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
			// THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			return cursor.getString(column_index);
		} else
			return null;
	}
}
